package com.mine.java.future.price;

import com.mine.java.future.PrintUtils;

import java.util.Comparator;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

/**
 * @author weixiao
 * @date 2025/3/27 14:43
 */
public class Test {

    public static void main(String[] args) {
        // serialCal("iPhone14");
        completableFutureCal("iPhone14");
    }

    /**
     * 串行计算
     */
    private static void serialCal(String product) {
        long start = System.currentTimeMillis();
        // 计算各个平台的价格
        PriceResult tbResult = MockHttpRequest.getPriceResult(product, "TB");
        MockHttpRequest.calFinalPrice(tbResult);
        PriceResult jdResult = MockHttpRequest.getPriceResult(product, "JD");
        MockHttpRequest.calFinalPrice(jdResult);
        PriceResult pddResult = MockHttpRequest.getPriceResult(product, "PDD");
        MockHttpRequest.calFinalPrice(pddResult);

        // 求最小价格
        PriceResult minResult =
                Stream.of(tbResult, jdResult, pddResult).min(Comparator.comparing(PriceResult::getFinalPrice)).get();
        PrintUtils.print(minResult.toString());
        long end = System.currentTimeMillis();
        System.out.println("cost = " + (end - start));
    }

    /**
     * 使用CompletableFuture计算
     */
    private static void completableFutureCal(String product) {
        long start = System.currentTimeMillis();
        // 获取价格和折扣并行计算，然后计算最终价格
        CompletableFuture<PriceResult> tbFuture = CompletableFuture
                .supplyAsync(() -> MockHttpRequest.getPriceResult(product, "TB"))
                .thenCombine(CompletableFuture.supplyAsync(() -> MockHttpRequest.getDisCount("TB")), (result, discount) -> {
                    result.setFinalPrice(result.getOriginalPrice().subtract(discount));
                    return result;
                });
        CompletableFuture<PriceResult> jdFuture = CompletableFuture
                .supplyAsync(() -> MockHttpRequest.getPriceResult(product, "JD"))
                .thenCombine(CompletableFuture.supplyAsync(() -> MockHttpRequest.getDisCount("JD")), (result, discount) -> {
                    result.setFinalPrice(result.getOriginalPrice().subtract(discount));
                    return result;
                });
        CompletableFuture<PriceResult> pddFuture = CompletableFuture
                .supplyAsync(() -> MockHttpRequest.getPriceResult(product, "PDD"))
                .thenCombine(CompletableFuture.supplyAsync(() -> MockHttpRequest.getDisCount("PDD")), (result, discount) -> {
                    result.setFinalPrice(result.getOriginalPrice().subtract(discount));
                    return result;
                });
        PriceResult minResult = Stream.of(tbFuture, jdFuture, pddFuture)
                .map(CompletableFuture::join)
                .min(Comparator.comparing(PriceResult::getFinalPrice))
                .get();
        PrintUtils.print(minResult.toString());
        long end = System.currentTimeMillis();
        System.out.println("cost = " + (end - start));
    }
}
